package com.mazaiting.redeye.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

/***
 *
 *
 *                                                    __----~~~~~~~~~~~------___
 *                                   .  .   ~~//====......          __--~ ~~
 *                   -.            \_|//     |||\\  ~~~~~~::::... /~
 *                ___-==_       _-~o~  \/    |||  \\            _/~~-
 *        __---~~~.==~||\=_    -_--~/_-~|-   |\\   \\        _/~
 *    _-~~     .=~    |  \\-_    '-~7  /-   /  ||    \      /
 *  .~       .~       |   \\ -_    /  /-   /   ||      \   /
 * /  ____  /         |     \\ ~-_/  /|- _/   .||       \ /
 * |~~    ~~|--~~~~--_ \     ~==-/   | \~--===~~        .\
 *          '         ~-|      /|    |-~\~~       __--~~
 *                      |-~~-_/ |    |   ~\_   _-~            /\
 *                           /  \     \__   \/~                \__
 *                       _--~ _/ | .-~~____--~-/                  ~~==.
 *                      ((->/~   '.|||' -_|    ~~-/ ,              . _||
 *                                 -_     ~\      ~~---l__i__i__i--~~_/
 *                                 _-~-__   ~)  \--______________--~~
 *                               //.-~~~-~_--~- |-------~~~~~~~~
 *                                      //.-~~~--\
 *                               神兽保佑
 *                              代码无BUG!
 * @author mazaiting
 * @date 2019-06-20
 * @decription JackJson 工具类
 */
public class JackJsonUtil {
    /**
     * 对象集合
     */
    private static ObjectMapper sObjectMapper;

    /**
     * 检测 ObjectMapper 对象
     */
    private static void checkObjectMapper() {
        // 如果对象集合为空，则创建
        if (null == sObjectMapper) sObjectMapper = new ObjectMapper();
    }

    /**
     * 将字符串转换为对象
     * @param content 内容
     * @param valueType 对象类型
     * @param <T> 泛型
     * @return 泛型对象
     */
    public static <T> T formJson(String content, Class<T> valueType) {
        return fromJson(new JsonCallback() {
            @Override
            public T json() throws IOException {
                return sObjectMapper.readValue(content, valueType);
            }
        });
    }

    /**
     * 将字符串转换为对象
     * @param content 内容
     * @param valueTypeRef 值引用类型
     * @param <T> 泛型
     * @return 泛型对象
     */
    public static <T> T formJson(String content, TypeReference valueTypeRef) {
        return fromJson(new JsonCallback() {
            @Override
            public T json() throws IOException {
                return (T)sObjectMapper.readValue(content, valueTypeRef);
            }
        });
    }

    /**
     * 将 JSON 数据转换为对象
     * @param callback 回调
     * @param <T> 泛型
     * @return 泛型对象
     */
    private static <T> T fromJson(JsonCallback callback) {
        checkObjectMapper();
        T obj = null;
        try {
            if (null != callback) {
                // 将字符串转换为对象
                obj = callback.json();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return obj;
    }

    /**
     * 将对象转换为 JSON 数据
     * @param object 对象
     * @return 字符串
     */
    public static String toJson(Object object) {
        // 如果对象集合为空，则创建
        checkObjectMapper();
        try {
            // 将对象转换为字符串
            return sObjectMapper.writeValueAsString(object);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * JSON 回调
     */
    public interface JsonCallback {
        /**
         * 解析 JSON
         * @param <T> 泛型
         * @return 泛型
         * @throws IOException 异常
         */
        <T> T json() throws IOException;
    }
}
